袁志刚 - 6.16 考后直奔杭州 Java 后端(含 AI Agent 经验)实习极速面试准备计划
🎯 核心求职定位与破局战略
- 定位:Java 研发实习生(主打差异化优势:大模型应用 / AI Agent / RAG 落地工程化实践)
- 核心卖点:
- AI 大模型工程落地能力(超级护城河):Spring AI + AI Agent(多步编排、工具白名单过滤、挂起与恢复、大模型事实提取记忆系统)+ 基于 Pgvector 的完整 Hybrid RAG 检索(多路召回 + RRF 融合 + Reranker 精排)+ 基于 Redisson 滑动窗口的双通道限流与基于 JVM 内存的 FAQ 语义缓存优化。
- 高并发后端基本功(防线保障):Caffeine + Redis 二级缓存一致性,Redis + Lua 一人一单高并发秒杀优化,Redis 延迟队列与事件订阅异步解耦削峰。
- 扎实的基础背景:华北理工计算机本科,GPA 前 20%,CET-6,蓝桥杯省二。
- 算法通关策略(主攻 LeetCode Hot 100 核心 35 题):
- 针对阿里、蚂蚁、网易、有赞等杭州中大厂的算法手撕硬性要求,绝不进行盲目题海战术。
- 核心战术:每天抽出 1.5 - 2 小时精刷并手写 2-3 道 Hot 100 中最具代表性的中等/简单题,掌握经典模板与套路。重点关注链表、双指针、二叉树和回溯(大厂超高频必考)。
📅 黄金备战与投递时间线 (5.31 - 6.30)
由于您期末考试科目备考压力较轻,且手上无其他项目,从今天起开启每日 6-8 小时高强度备战模式,备考与求职多轨运行:
| 阶段 | 时间段 | 精力分配 | 核心任务 |
|---|---|---|---|
| 第一阶段:高能黄金备战期 | 5.31 - 6.4 (5天) | 每日 6-8 小时 | 1. 简历防线建立:对照下文“简历防御系统”,彻底抠烂简历上两个项目的技术实现细节,整理出 1-3 分钟自我介绍与项目答辩词。 2. 算法突击:刷完算法极速题单的前 15 题(链表、双指针、滑动窗口)。 3. 传统八股:复习 Java 集合(HashMap/ConcurrentHashMap 源码)、Java 并发核心(AQS, 线程池, 锁升级)。 |
| 第二阶段:试水投递与核心进阶期 | 6.5 - 6.10 (6天) | 每日 6-8 小时(扣除考前突击) | 1. 开启试水投递:在 Boss 直聘投递杭州的中小厂、中型互联网公司,磨练真实面试手感。 2. 算法进阶:精刷题单中的二叉树与回溯模块。 3. 传统八股:MySQL(B+树、隔离级别、MVCC)与 Redis(双写一致性、穿透击穿雪崩、分布式锁原理)。 4. 考试轻量突击: - 6.9 晚上 + 6.10 下午:全力突击《机器学习》与《Web 应用开发》(腾出半天到一天极速通关)。 |
| 第三阶段:冲刺与蓄水决战期 | 6.11 - 6.17 (7天) | 每日 4-5 小时力保考试,其余时间求职 | 1. 全力备考:主攻《软件架构与设计模式》(给 1-1.5 天),保障全部科目顺利高分通关! 2. 网申蓄水:6.12 左右开始在 Boss / 牛客网疯狂投递杭州心仪的第一梯队大厂 / 中厂(阿里系、网易、蚂蚁、有赞),把面试约到 6.18 及以后。 3. 快速过一遍 AI 大模型与 RAG 专项面试八股,保持代码和理论手感。 |
| 第四阶段:全职面试狂飙期 | 6.18 - 6.30 (考后) | 全天拉满 | 1. 直奔杭州(或进行高频线上线下面试)。 2. 保持每日投递 30+,每日 1-2 场面试的节奏。 3. 重要:每场面试后 1 小时内必须复盘录音,没答好的点立即查漏补缺,更新八股库。 |
💻 算法手撕极速突击:LeetCode Hot 100 必背 35 题
大厂手撕重在套路,以下 35 题为大厂 Java 岗最爱考的经典高频题,请确保能在 IDE / 纸上无编译错误地快速写出:
1. 链表模块(最高频,要求无条件一次性手撕成功)
- LC 206. 反转链表 (Easy) —— 核心中的核心,熟练掌握双指针迭代与递归写法。
- LC 141. 环形链表 (Easy) —— 快慢指针判断是否有环。
- LC 142. 环形链表 II (Medium) —— 快慢指针找环入口(数学推导 $a=c+(n-1)(b+c)$ 要会)。
- LC 21. 合并两个有序链表 (Easy) —— 经典迭代或递归。
- LC 25. K 个一组翻转链表 (Hard) —— 阿里、网易超高频手撕题,掌握分组反转的迭代解法。
- LC 160. 相交链表 (Easy) —— 浪漫的双指针指针相遇法。
2. 双指针与滑动窗口(解决数组与字符串的利器)
- LC 1. 两数之和 (Easy) —— 一次哈希映射。
- LC 15. 三数之和 (Medium) —— 排序 + 双指针左右夹逼(去重细节是重难点)。
- LC 3. 无重复字符的最长子串 (Medium) —— 滑动窗口经典,各厂超高频。
- LC 11. 盛最多水的容器 (Medium) —— 左右指针向内收缩。
- LC 209. 长度最小的子数组 (Medium) —— 滑动窗口,动态调节窗口大小。
3. 二叉树与深度/广度优先搜索(理解递归与分治)
- LC 102. 二叉树的层序遍历 (Medium) —— 队列实现 BFS 经典模板。
- LC 226. 翻转二叉树 (Easy) —— 递归基础。
- LC 104. 二叉树的最大深度 (Easy) —— 递归基础。
- LC 236. 二叉树的最近公共祖先 (Medium) —— 递归经典,极其高频。
- LC 94. 二叉树的中序遍历 (Easy) —— 递归与非递归(栈辅助)实现。
4. 回溯算法(掌握“万能回溯模板”)
- LC 46. 全排列 (Medium) —— 最基础的回溯(不含重复元素)。
- LC 39. 组合总和 (Medium) —— 元素可重复选取的剪枝回溯。
- LC 22. 括号生成 (Medium) —— 左右括号数量约束下的回溯。
5. 动态规划与贪心(理解状态转移方程与贪心策略)
- LC 70. 爬楼梯 (Easy) —— 基础斐波那契,动态规划入门。
- LC 121. 买卖股票的最佳时机 (Easy) —— 一次遍历维护最低价格与最大利润。
- LC 322. 零钱兑换 (Medium) —— 完全背包问题的 DP 实现(大厂常考)。
- LC 300. 最长递增子序列 (Medium) —— $O(n^2)$ 的 DP / $O(n\log n)$ 的二分查找(阿里爱问优化版)。
- LC 53. 最大子数组和 (Medium) —— 动态规划或贪心解法。
- LC 198. 打家劫舍 (Medium) —— 经典相邻不重复选取 DP。
- LC 55. 跳跃游戏 (Medium) —— 贪心维护最大可达范围。
6. 栈、队列与快速排序相关
- LC 20. 有效的括号 (Easy) —— 辅助栈应用。
- LC 215. 数组中的第 K 个最大元素 (Medium) —— 大厂必考! 堆排序(Java PriorityQueue)或快速选择算法(Quick Select,必须掌握)。
7. 二分查找与哈希/矩阵(精准定位与空间换时间)
- LC 704. 二分查找 (Easy) —— 经典折半查找基础。
- LC 34. 在排序数组中查找元素的第一个和最后一个位置 (Medium) —— 二分查找左右边界极高频变体。
- LC 33. 搜索旋转排序数组 (Medium) —— 变形二分,判断哪侧有序并针对性查找。
- LC 128. 最长连续序列 (Medium) —— 哈希去重实现 $O(n)$ 复杂度查找。
- LC 48. 旋转图像 (Medium) —— 顺时针旋转二维矩阵(原处修改)。
- LC 240. 搜索二维矩阵 II (Medium) —— 从右上角或左下角消减行列的经典检索法。
8. 图论与拓扑排序(契合项目任务编排与依赖管理)
- LC 207. 课程表 (Medium) —— 经典拓扑排序,判断有向图是否有环(DFS / BFS 入度表),与 AI Agent 任务编排状态机设计高度相关。
🛡️ 简历核心战壕防御系统(面试官灵魂发问与高分对答模板)
第一防御阵地:苍穹外卖 AI 智能客服 Agent
问 1:大模型容易产生工具调用幻觉,如何识别用户意图并防止 LLM 陷入无限的工具调用死循环(Tool Call Loop)?
- 答题套路:
- 层级级联意图识别与工具白名单:我不把系统几十个 Function Tools 一股脑塞给大模型,而是先使用轻量级 Prompt / 语义识别(或 Spring AI Advisor)识别出大类意图(如“购物车意图”)。只给 LLM 下发对应的 工具白名单(如仅下发购物车相关的 6 个 Tools ),从物理上阻断无关幻觉。
- 最大调用轮次截断:在 Spring AI Tool 调用执行拦截器中配置计数,限制单次会话最大工具调用次数(Max Tool Call Count = 3)。
- 调用签名防御:在拦截器中检测工具入参 of the 哈希签名,如果连续出现相同入参的连续调用,判定为幻觉死循环,立即主动熔断并转为人工。
问 2:在多步任务编排中,涉及高风险操作(如批量取消、退款),如果网络抖动或系统崩溃,状态如何恢复?如何保证安全?
- 答题套路:
- 工作流状态持久化:不依赖大模型连续输出,而是将“查询-核对-退款”拆解为有序的步骤状态机。
- Redis 挂起与异步确认:当遇到“退款”、“取消”等高风险步骤时,后台不自动执行,而是通过 Redis 持久化一个
WAITING_CONFIRM挂起状态与当前上下文,并将确认卡片推送给前端。待用户点击“确认”触发 REST API 后,再从 Redis 中反序列化上下文恢复执行。 - 动态超时预算:设置步骤级别的超时熔断(Timeout Budget),超时未确认则自动作废或回滚状态,系统可用性达 99.5%。
问 3:用户记忆系统如何避免噪音数据并差异化注入上下文?如何保证数据的实时修正?
- 答题套路:
- 异步提取与置信度过滤:对话结束后,异步将对话上下文投递至任务队列,调用 LLM 提取结构化事实(偏好、忌口等)。为了避免闲聊噪音,设定置信度阈值(Confidence Score = 0.7),低于 0.7 自动丢弃。
- 三档粒度差异化注入:为了防止上下文膨胀,根据意图类型对记忆进行差异化注入:例如“点单意图”注入全量喜好,“地址意图”仅注入摘要,无关意图不注入。
- 审计与用户修正:提供 REST API 允许用户手动修改或删除错误的记忆事实,并保留审计变更历史,是个性化推荐准确率提升的工程基础。
问 4:你们的 Hybrid RAG 是如何落地并保证 99.4% 客服回答准确率的?
- 答题套路:
- 差异化切片(Chunking):针对 QA 常见问答按“问答对”切分;对于 Markdown 文档,按照一二级标题物理层级切割,并在子 Chunk 中携带父级 Title 路径,保留语义上下文。
- 双路检索(Hybrid Search):在线阶段,利用 Pgvector 进行向量相似度检索(语义召回),同时利用 MySQL/ElasticSearch 进行传统全文检索(精准词匹配)。
- 混合融合与重排(RRF + Reranker):两路结果各取 Top N,使用 RRF(互惠排名融合)算法进行无监督得分融合,最后送入 BGE-Reranker 重排模型做精准精排,只留 Top 3 喂给 LLM,大幅削弱了大模型的幻觉。
- 查询扩展(Query Expansion):利用大模型对用户模糊提问进行同义词扩展与纠错(Query Rephrase),提升检索召回率。
问 5:如何应对高频 FAQ 带来的算力浪费与 WebSocket 长连接流控?
- 答题套路:
- Advisor 最前置语义缓存:在 Spring AI Advisor 链最前端,将 FAQ 数据全量异步拉取到 JVM 本地 ConcurrentHashMap 缓存。用户提问时,直接计算提问向量与 FAQ 向量的余弦相似度,若相似度 > 0.95 则直接短路返回标准答案,跳过后续 RAG 和大模型生成。
- Redis Pub/Sub 广播更新:当后台 FAQ 变更时,发布
faq_sync广播,多实例节点订阅后异步重载本地缓存,确保多实例缓存的最终一致性。 - 双通道限流保护:基于 Redisson 滑动窗口限流器,对 HTTP 接口(AOP 切面拦截)与 WebSocket 长连接通道(WebSocketHandler 拦截)进行双重流控,保障昂贵的大模型算力不被刷爆。
问 6:针对订单状态流转的并发竞争和支付回调,后端如何做防重/防超卖/幂等保障?
- 答题套路:
- 条件更新(CAS思想)实现原子写:在修改订单状态时(如从未支付修改为已支付),SQL 使用条件控制
update tbl_order set status = 2 where id = xxx and status = 1,保证流转不出现并发竞争。 - 唯一约束拦截重复回调(幂等保障):设计“支付回调记录表”以
trade_no(或者支付平台流水号)作为唯一索引。回调进来先插入记录表,利用数据库唯一约束强制拦截重复回调,确保支付链路幂等性。
- 条件更新(CAS思想)实现原子写:在修改订单状态时(如从未支付修改为已支付),SQL 使用条件控制
第二防御阵地:黑马点评高并发实战
问 1:高并发下如何实现 Caffeine 与 Redis 的二级缓存一致性?
- 答题套路:
- 读取链路:Caffeine 本地缓存(最快) -> Redis 分布式缓存 -> MySQL 数据库。
- 缓存失效策略:采用**“先更新数据库,再删除 Redis 缓存”**的主动失效策略。
- 二级同步一致性:为了同步清除各应用节点的 Caffeine 本地缓存,利用 Redis 的 Pub/Sub 机制(或 Canal 监听 binlog 投递至 RabbitMQ 消息队列)。当 Redis 缓存被删除时,发布一条删除本地缓存的消息,所有 JVM 节点订阅后同步失效本地 Caffeine,保障多级缓存最终一致性。
问 2:秒杀场景下,如何解决“超卖”和“一人一单”高并发下的并发竞争问题?
- 答题套路:
- 库存预扣减 + Lua 脚本:把秒杀资格校验(库存是否充足、用户是否已经购买过)下沉到 Redis。使用 Lua 脚本将“校验库存”、“校验一人一单”、“扣减库存”打包成单线程原子性操作,直接阻断了高并发下的并发穿透。
- Redisson 分布式锁兜底:为了防止极端情况下集群环境中的一人一单失效,在生成订单阶段,使用以
userId为 key 的 Redisson 分布式锁进行锁控制,配合锁的看门狗机制(自动续期)及防止释放他人锁的 UUID 校验。 - 延迟队列与削峰:预扣减成功后,将抢单成功的
userId与voucherId投递到 Redis 延迟队列/消息队列中,后台异步消费生成订单,实现削峰填谷。
📚 传统核心八股极速通关点
1. Java 核心与并发
- HashMap 源码:1.7(数组+链表,头插法死循环)与 1.8(数组+链表+红黑树,尾插法,红黑树阈值 8 与 64)区别,扩容机制(2倍扩容,
hash & oldCap == 0的位置保持,否则为index + oldCap)。 - ConcurrentHashMap:1.7的分段锁(Segment 继承自 ReentrantLock),1.8的 CAS + synchronized(锁链表/红黑树的头节点),锁粒度显著细化。
- 线程池:7大核心参数,4大拒绝策略,线程池的工作流程(核心线程 -> 阻塞队列 -> 最大线程 -> 拒绝策略),合理配置线程数(CPU密集型为 $N+1$,IO密集型为 $2N$ 或根据公式计算)。
- AQS (AbstractQueuedSynchronizer):底层原理(state状态变量、双向 CLH 队列、CAS 竞争锁),ReentrantLock 的非公平与公平实现。
- JMM (Java 内存模型):可见性、原子性、有序性,volatile 关键字原理(禁止指令重排、内存屏障、强制刷新主内存,但无法保证
i++的原子性)。
2. MySQL 与 Redis 数据库
- MySQL 索引:B+树的结构(为什么不用二叉树/红黑树?层高低,IO次数少;为什么不用B树?非叶子节点不存数据,单页能存更多键值;便于范围查询)、聚簇索引与非聚簇索引、最左前缀法则、索引失效场景。
- 事务与隔离级别:ACID 特性(原子、一致、隔离、持久)、四种隔离级别(读未提交、读已提交、可重复读、串行化)。
- MVCC (多版本并发控制):底层原理(ReadView 读视图、Undo Log 回滚日志、隐藏列
trx_id和roll_pointer)。 - Redis 双写一致性:延迟双删、MQ异步更新、Canal binlog订阅。
- 缓存三山:
- 穿透(查不存在的 Key):布隆过滤器、缓存空值。
- 击穿(热点 Key 失效):逻辑过期(异步构建)、互斥锁(SETNX)。
- 雪崩(大批 Key 同时失效):随机过期时间、Sentinel/Cluster集群、多级缓存。
- 分布式锁实现:SETNX 缺点,Redisson 核心(Watch Dog 自动续期,Lua 脚本原子加锁与释放)。
3. Spring 框架
- IoC 与 AOP:控制反转与面向切面编程。JDK 动态代理(代理接口)与 CGLIB 代理机制(子类代理,代理类不能被 final 修饰)。
- Bean 生命周期:实例化 -> 属性填充 -> 初始化前(BeanPostProcessor.postProcessBeforeInitialization) -> 初始化(InitializingBean/init-method) -> 初始化后(AOP代理在此产生) -> 销毁。
- 循环依赖:三级缓存解决原理(一级缓存单例池,二级缓存早期暴露半成品,三级缓存 ObjectFactory 代理工厂解决 AOP 动态代理 Bean 提前暴露)。